<template>
  <div class="container mx-auto px-4">
    <div class="max-w-5xl mx-auto">
      <!-- 主标题 -->
      
      
      <!-- 卡片和输入区域 -->
      <div class="flex flex-col md:flex-row gap-6 mb-16">
        <!-- 左侧输入区域 -->
        <div class="w-full md:w-1/2 fade-in" style="animation-delay: 0.05s;">
          <el-card class="h-full card-glass" shadow="hover" :body-style="{ padding: '24px' }">
            <h2 class="text-lg font-medium mb-4 pb-3 border-b border-gray-100 dark:border-gray-700 flex items-center">
              <el-icon class="mr-2 text-primary"><el-icon-magic-stick /></el-icon>
              <span class="bg-clip-text text-transparent bg-gradient-to-r from-primary to-accent">汉语新解 | 给汉语一个全新的解释</span>
            </h2>
            
            <div class="mb-5">
              <h3 class="text-sm text-gray-700 dark:text-gray-300 mb-2 font-medium">汉语输入</h3>
              <el-input 
                v-model="text" 
                placeholder="输入一个汉语词汇" 
                :prefix-icon="Search"
                clearable
                class="hover:shadow-sm transition-shadow duration-300"
                @keyup.enter="generateExplanation"
              />
            </div>
            
            <div class="mb-6">
              <h3 class="text-sm text-gray-700 dark:text-gray-300 mb-2 font-medium">推荐词汇</h3>
              <div class="flex flex-wrap gap-2">
                <el-tag
                  v-for="item in presetTemplates"
                  :key="item.prompt"
                  class="cursor-pointer transition-all duration-300 hover:scale-105 hover:shadow-sm py-1 px-2"
                  @click="selectTemplate(item)"
                  effect="plain"
                  size="small"
                >
                  {{ item.prompt }}
                </el-tag>
              </div>
            </div>
            
            <el-button
              type="primary"
              :loading="loading"
              @click="generateExplanation"
              class="w-full hover:shadow-md transition-all duration-300"
              :disabled="!text"
            >
              <span class="flex items-center justify-center">
                <el-icon v-if="!loading" class="mr-1"><el-icon-magic-stick /></el-icon>
                {{ loading ? '生成中...' : '生成汉语解释' }}
              </span>
            </el-button>
          </el-card>
        </div>
        
        <!-- 右侧显示区域 -->
        <div class="w-full md:w-1/2 fade-in" style="animation-delay: 0.1s;">
          <el-card class="h-full card-glass" shadow="hover" :body-style="{ padding: '24px', minHeight: '450px', display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' }">
              <!-- 加载中状态 -->
              <div v-if="loading && !streamContent" class="text-center py-8 loading-container">
                <div class="relative w-20 h-20 mx-auto mb-6">
                  <div class="absolute top-0 left-0 w-20 h-20 rounded-full border-4 border-gray-200 dark:border-gray-700"></div>
                  <div class="absolute top-0 left-0 w-20 h-20 rounded-full border-4 border-t-primary border-r-accent animate-spin"></div>
                </div>
                <div class="loading-text">
                  <p class="loading-title">正在好努力的生成！！！！</p>
                  <p class="loading-subtitle">但是deepseekAPI超慢，再等等</p>
                </div>
              </div>
              
              <!-- 结果显示区域 -->
              <div v-else class="w-full h-full flex flex-col">
                <!-- 生成过程中显示文本内容 (现代仪表盘风格) -->
                <div v-if="loading && streamContent" class="dashboard-container fade-in">
                  <div class="dashboard-header">
                    <div class="dashboard-title">
                      <span class="dashboard-icon"></span>
                      <span>实时生成内容</span>
                    </div>
                    <div class="dashboard-stats">
                      <div class="stat-item">
                        <div class="stat-label">已生成</div>
                        <div class="stat-value">{{ displayContent.length }} 字符</div>
                      </div>
                      <div class="stat-item">
                        <div class="stat-label">状态</div>
                        <div class="stat-value status-active">活跃</div>
                      </div>
                    </div>
                  </div>
                  <div class="dashboard-content">
                    <div class="progress-indicator">
                      <div class="progress-bar"><div class="progress-fill"></div></div>
                      <div class="progress-pulse"></div>
                    </div>
                    <div class="content-wrapper">
                      <div class="line-numbers">
                        <div v-for="i in Math.max(1, displayContent.split('\n').length)" :key="i" class="line-number">{{ i }}</div>
                      </div>
                      <div class="content-area">
                        <pre><code class="code-highlight" v-html="formatStreamContent(displayContent)"></code></pre>
                        <span class="typing-cursor"></span>
                      </div>
                    </div>
                  </div>
                </div>
                
                <!-- 显示生成进度 -->
                <div v-if="loading && svgDetected" class="text-center py-3 text-sm text-gray-600 dark:text-gray-400">
                  <span>SVG已检测到，正在完成生成...</span>
                </div>
                
                <!-- 生成完成后显示SVG -->
                <transition name="svg-fade" appear>
                  <div v-if="svg && !loading" class="svg-display-container flex-grow flex items-center justify-center">
                    <div ref="svgRef" v-html="svg" class="svg-result-container" @click="openPreview"></div>
                  </div>
                </transition>
                
                <!-- 空状态 -->
                <div v-if="!loading && !svg && !streamContent" class="empty-state-container">
                  <div class="empty-state">
                    <div class="icon-container">
                      <el-icon class="empty-icon"><el-icon-picture /></el-icon>
                    </div>
                    <h3 class="empty-title">生成汉语解释</h3>
                    <p class="empty-desc">生成的汉语解释将显示在这里</p>
                  </div>
                </div>
                
                <!-- 按钮区域 -->
                <div v-if="svg && !loading" class="action-buttons flex flex-wrap gap-3 justify-center mt-4 pb-2">
                  <el-button 
                    @click="downloadImage"
                    :icon="Download"
                    class="hover:shadow-md transition-all duration-300"
                  >
                    下载图片
                  </el-button>
                  <el-button 
                    @click="copyImageToClipboard"
                    :icon="CopyDocument"
                    class="hover:shadow-md transition-all duration-300"
                  >
                    复制图片 (PC端)
                  </el-button>
                  <el-button 
                    @click="copySvg"
                    :icon="Document"
                    class="hover:shadow-md transition-all duration-300"
                  >
                    复制SVG
                  </el-button>
                </div>
              </div>
          </el-card>
        </div>
      </div>
      
      <!-- 预设模板展示 -->
      <div class="fade-in mb-8" style="animation-delay: 0.15s;">
        <h2 class="text-2xl font-bold mb-6 flex items-center justify-center">
     
          <span class="bg-clip-text text-transparent bg-gradient-to-r from-primary to-accent">汉语新解例子</span>
        </h2>
        <PresetTemplateGrid :templates="presetTemplates" @select="selectTemplate" />
      </div>
    </div>
    
    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      :width="'400px'"
      center
      :append-to-body="true"
      :show-close="true"
      @close="closePreview"
      class="preview-dialog"
      title="SVG预览"
    >
      <div class="preview-container">
        <div class="preview-svg-container" v-html="svg"></div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref } from 'vue';
import { generateCardExplanation } from '../services/api';
import { presetTemplates } from '../constants/presetTemplates';
import { downloadSvgAsPng, copySvgToClipboard } from '../utils/svg-utils';
import PresetTemplateGrid from './PresetTemplateGrid.vue';
import { Search, Download, CopyDocument, Document, Loading, Picture, MagicStick, Collection } from '@element-plus/icons-vue';
import { ElMessage, ElIcon } from 'element-plus';

export default {
  name: 'CardGenerator',
  components: {
    PresetTemplateGrid,
    ElIcon,
    ElIconLoading: Loading,
    ElIconPicture: Picture,
    ElIconMagicStick: MagicStick,
    ElIconCollection: Collection
  },
  setup() {
    const text = ref('');
    const svg = ref('');
    const loading = ref(false);
    const error = ref('');
    const svgRef = ref(null);
    const streamContent = ref(''); // 流式内容
    const displayContent = ref(''); // 用于显示的内容
    const svgDetected = ref(false); // 是否检测到SVG
    const previewVisible = ref(false); // 预览对话框可见状态
    const svgContent = ref(''); // 用于存储SVG内容的临时变量
    
    // 处理流式更新
    const handleStreamUpdate = (update) => {
      if (update.error) {
        error.value = update.error;
        loading.value = false;
        return;
      }
      
      streamContent.value = update.text;
      displayContent.value = update.text;
      svgDetected.value = update.svgDetected;
      
      if (update.svgContent) {
        svgContent.value = update.svgContent;
        
        // 等SVG内容准备好后，如果流程结束再显示
        if (!update.inProgress) {
          // 短暂延迟后再显示SVG，给动画时间
          setTimeout(() => {
            svg.value = svgContent.value;
            loading.value = false;
          }, 800); // 匹配过渡动画时间
        }
      } else if (!update.inProgress && update.svgDetected) {
        const svgMatch = update.text.match(/<svg[\s\S]*?<\/svg>/);
        if (svgMatch) {
          svgContent.value = svgMatch[0];
          
          // 短暂延迟后再显示SVG，给动画时间
          setTimeout(() => {
            svg.value = svgContent.value;
            loading.value = false;
          }, 800); // 匹配过渡动画时间
        } else {
          loading.value = false;
        }
      } else if (!update.inProgress) {
        loading.value = false;
        if (update.text) {
          ElMessage({
            message: '生成成功',
            type: 'success'
          });
        } else {
          ElMessage.error('生成失败，请稍后重试');
        }
      }
    };
    
    const generateExplanation = async () => {
      if (!text.value) {
        ElMessage.warning('请输入汉语词汇');
        return;
      }
      
      loading.value = true;
      error.value = '';
      svg.value = '';
      streamContent.value = '';
      displayContent.value = '';
      svgDetected.value = false;
      svgContent.value = ''; // 确保临时变量清空
      
      try {
        await generateCardExplanation(text.value, handleStreamUpdate);
      } catch (err) {
        console.error('生成解释错误:', err);
        error.value = err.message || '生成解释时出现错误';
        ElMessage.error('生成解释时出现错误');
        loading.value = false;
      }
    };
    
    const selectTemplate = (template) => {
      if (!template) return;
      text.value = template.prompt;
      svg.value = template.svg;
      streamContent.value = '';
      displayContent.value = '';
      svgContent.value = ''; // 确保临时变量清空
    };
    
    const getTemplateByPrompt = (prompt) => {
      return presetTemplates.find(t => t.prompt === prompt) || null;
    };
    
    const downloadImage = () => {
      if (!svg.value) return;
      downloadSvgAsPng(svg.value, `汉语新解-${text.value}`);
    };
    
    const copyImageToClipboard = async () => {
      if (!svg.value) return;
      
      const success = await copySvgToClipboard(svg.value);
      if (success) {
        ElMessage.success('图片已复制到剪贴板');
      } else {
        ElMessage.error('复制图片失败');
      }
    };
    
    const copySvg = async () => {
      if (!svg.value) return;
      
      try {
        await navigator.clipboard.writeText(svg.value);
        ElMessage.success('SVG代码已复制到剪贴板');
      } catch (error) {
        console.error('复制SVG失败:', error);
        ElMessage.error('复制SVG失败');
      }
    };
    
    // 打开预览
    const openPreview = () => {
      if (svg.value) {
        previewVisible.value = true;
      }
    };
    
    // 关闭预览
    const closePreview = () => {
      previewVisible.value = false;
    };
    
    // 格式化流输出内容，处理代码高亮
    const formatStreamContent = (content) => {
      if (!content) return '';
      
      // 处理SVG标签显示
      let formattedContent = content
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        // SVG标签
        .replace(/&lt;svg/g, '<span class="tag">&lt;svg</span>')
        .replace(/&lt;\/svg&gt;/g, '<span class="tag">&lt;/svg&gt;</span>')
        .replace(/&lt;rect/g, '<span class="tag">&lt;rect</span>')
        .replace(/&lt;text/g, '<span class="tag">&lt;text</span>')
        .replace(/&lt;\/text&gt;/g, '<span class="tag">&lt;/text&gt;</span>')
        .replace(/&lt;tspan/g, '<span class="tag">&lt;tspan</span>')
        .replace(/&lt;\/tspan&gt;/g, '<span class="tag">&lt;/tspan&gt;</span>')
        .replace(/&lt;line/g, '<span class="tag">&lt;line</span>')
        .replace(/&lt;circle/g, '<span class="tag">&lt;circle</span>')
        .replace(/&lt;path/g, '<span class="tag">&lt;path</span>')
        .replace(/&lt;defs/g, '<span class="tag">&lt;defs</span>')
        .replace(/&lt;\/defs&gt;/g, '<span class="tag">&lt;/defs&gt;</span>')
        .replace(/&lt;g/g, '<span class="tag">&lt;g</span>')
        .replace(/&lt;\/g&gt;/g, '<span class="tag">&lt;/g&gt;</span>');
      
      // 处理属性高亮
      const attributes = [
        'width', 'height', 'fill', 'stroke', 'x', 'y', 'cx', 'cy', 'r', 
        'd', 'font-family', 'font-size', 'text-anchor', 'viewBox', 'xmlns',
        'opacity', 'stroke-width', 'points', 'transform', 'dy', 'dx', 'version',
        'encoding', 'dominant-baseline', 'fill-opacity', 'text-decoration',
        'font-weight', 'font-style', 'text-transform'
      ];
      
      attributes.forEach(attr => {
        const regex = new RegExp(`${attr}=`, 'g');
        formattedContent = formattedContent.replace(regex, `<span class="attribute">${attr}</span>=`);
      });
      
      // 处理引号中的值
      formattedContent = formattedContent.replace(/"([^"]*)"/g, '"<span class="value">$1</span>"');
      
      // 添加换行后的行缩进效果
      formattedContent = formattedContent.replace(/\n/g, '\n<span class="indent"></span>');
      
      return formattedContent;
    };

    return {
      text,
      svg,
      loading,
      error,
      svgRef,
      streamContent,
      displayContent,
      svgDetected,
      previewVisible,
      presetTemplates,
      generateExplanation,
      selectTemplate,
      getTemplateByPrompt,
      downloadImage,
      copyImageToClipboard,
      copySvg,
      openPreview,
      closePreview,
      Search,
      Download,
      CopyDocument,
      Document,
      formatStreamContent
    };
  }
};
</script>

<style>
.card-glass {
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: var(--radius-xl);
}

@media (prefers-color-scheme: dark) {
  .card-glass {
    background: rgba(31, 41, 55, 0.7);
    border: 1px solid rgba(55, 65, 81, 0.5);
  }
}

.fade-in {
  opacity: 0;
  transform: translateY(10px);
  animation: fadeInUp 0.5s ease-out forwards;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.float {
  animation: float 3s ease-in-out infinite;
}

@keyframes float {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

.svg-wrapper {
  width: 100%;
  padding: 1rem;
}

.svg-result-container {
  width: 280px;
  max-width: 100%;
  margin: 0 auto;
}

.svg-result-container svg {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
}

/* 流式内容容器样式 */
.stream-content-container {
  width: 100%;
  border-radius: 0.75rem;
  overflow: hidden;
  margin-bottom: 1rem;
  border: 1px solid rgba(203, 213, 225, 0.5);
  background: rgba(248, 250, 252, 0.8);
  backdrop-filter: blur(8px);
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
}

.dark .stream-content-container {
  background: rgba(30, 41, 59, 0.8);
  border-color: rgba(71, 85, 105, 0.5);
}

.stream-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  background: rgba(241, 245, 249, 0.9);
  border-bottom: 1px solid rgba(203, 213, 225, 0.5);
}

.dark .stream-header {
  background: rgba(51, 65, 85, 0.9);
  border-color: rgba(71, 85, 105, 0.5);
}

.stream-title {
  font-weight: 600;
  font-size: 0.875rem;
  color: #64748b;
}

.dark .stream-title {
  color: #94a3b8;
}

.stream-indicator {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.stream-dot {
  width: 0.5rem;
  height: 0.5rem;
  background-color: #10b981;
  border-radius: 50%;
  animation: pulse-green 1.5s infinite;
}

.stream-status {
  font-size: 0.75rem;
  color: #64748b;
}

.dark .stream-status {
  color: #94a3b8;
}

/* 流式内容样式 */
.stream-content {
  position: relative;
  padding: 1rem;
  max-height: 350px;
  overflow-y: auto;
  font-family: "Menlo", "Monaco", "Consolas", monospace;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
}

.stream-content pre {
  margin: 0;
  font-family: inherit;
}

.stream-content code {
  font-family: inherit;
  font-size: 0.875rem;
}

/* 代码高亮 */
.code-highlight {
  color: #334155;
}

.dark .code-highlight {
  color: #e2e8f0;
}

.code-highlight .tag {
  color: #2563eb;
}

.dark .code-highlight .tag {
  color: #60a5fa;
}

.code-highlight .attribute {
  color: #d97706;
}

.dark .code-highlight .attribute {
  color: #fbbf24;
}

.code-highlight .value {
  color: #059669;
}

.dark .code-highlight .value {
  color: #34d399;
}

/* 打字光标动画 */
.typing-cursor {
  display: inline-block;
  width: 2px;
  height: 1.2em;
  background-color: #3b82f6;
  margin-left: 2px;
  animation: blink 1s step-end infinite;
  vertical-align: middle;
}

@keyframes blink {
  from, to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

@keyframes pulse-green {
  0% {
    transform: scale(0.8);
    opacity: 1;
  }
  50% {
    transform: scale(1);
    opacity: 0.8;
  }
  100% {
    transform: scale(0.8);
    opacity: 1;
  }
}

/* 加载状态样式 */
.loading-container {
  max-width: 280px;
  margin: 0 auto;
}

.loading-text {
  animation: pulse 2s infinite ease-in-out;
}

.loading-title {
  font-family: "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  font-size: 1.25rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  letter-spacing: 0.025em;
  background: linear-gradient(to right, var(--color-primary, #3b82f6), var(--color-accent, #ec4899));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
}

.loading-subtitle {
  font-family: "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  font-size: 0.95rem;
  color: #6b7280;
  font-weight: 500;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.8;
  }
}

.action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

@media (max-width: 768px) {
  .action-buttons {
    display: none;
  }
}

/* 空状态样式 */
.empty-state-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.empty-state {
  width: 100%;
  max-width: 300px;
  text-align: center;
  padding: 1.5rem;
  border-radius: var(--radius-xl);
  background-color: rgba(255, 255, 255, 0.5);
  backdrop-filter: blur(4px);
  box-shadow: var(--shadow-sm);
}

@media (prefers-color-scheme: dark) {
  .empty-state {
    background-color: rgba(31, 41, 55, 0.5);
  }
}

.icon-container {
  width: 80px;
  height: 80px;
  margin: 0 auto 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(236, 72, 153, 0.1));
  box-shadow: var(--shadow-sm);
}

.empty-icon {
  font-size: 2.5rem;
  color: var(--color-primary);
}

.empty-title {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.75rem;
  color: var(--color-gray-800);
  background-clip: text;
  background-image: linear-gradient(to right, var(--color-primary), var(--color-accent));
  -webkit-background-clip: text;
  color: transparent;
}

.empty-desc {
  font-size: 0.95rem;
  color: var(--color-gray-500);
  margin-bottom: 1.5rem;
}

.empty-button {
  width: 100%;
  transition: all 0.3s ease;
}

.empty-button:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

@media (prefers-color-scheme: dark) {
  .empty-desc {
    color: var(--color-gray-400);
  }
  
  .icon-container {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(236, 72, 153, 0.2));
  }
}

.svg-display-container {
  width: 100%;
  padding: 1rem;
  min-height: 360px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.svg-result-container {
  width: 280px;
  max-width: 100%;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.svg-result-container:hover {
  transform: scale(1.02);
}

.svg-result-container svg {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
}

/* SVG淡入动画 */
.svg-fade-enter-active {
  transition: all 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.svg-fade-enter-from {
  opacity: 0;
  transform: scale(0.9);
}
.svg-fade-enter-to {
  opacity: 1;
  transform: scale(1);
}

/* 预览对话框样式 */
.preview-dialog :deep(.el-dialog) {
  border-radius: 12px;
  overflow: hidden;
  max-width: 400px;
}

.preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1rem;
}

.preview-svg-container {
  width: 100%;
  max-width: 350px;
  margin: 0 auto;
}

.preview-svg-container svg {
  width: 100%;
  height: auto;
  display: block;
  object-fit: contain;
}

@media (max-width: 768px) {
  .preview-dialog :deep(.el-dialog) {
    width: 95% !important;
    max-width: none;
  }
}

/* 现代仪表盘风格 */
.dashboard-container {
  width: 100%;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 1rem;
  background: rgba(17, 24, 39, 0.95);
  backdrop-filter: blur(12px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), 
              inset 0 0 0 1px rgba(255, 255, 255, 0.1),
              inset 0 0 0 1px rgba(79, 70, 229, 0.2);
  border: 1px solid rgba(99, 102, 241, 0.3);
  position: relative;
  height: 450px; /* 固定高度 */
  display: flex;
  flex-direction: column;
}

.dashboard-container::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, 
                rgba(99, 102, 241, 0), 
                rgba(99, 102, 241, 0.7) 50%, 
                rgba(99, 102, 241, 0));
  animation: glow 1.5s infinite ease-in-out;
}

.dashboard-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.8rem 1.2rem;
  background: rgba(30, 41, 59, 0.7);
  border-bottom: 1px solid rgba(99, 102, 241, 0.2);
}

.dashboard-title {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #e2e8f0;
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.5px;
}

.dashboard-icon {
  width: 12px;
  height: 12px;
  background: #4f46e5;
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(99, 102, 241, 0.7);
  position: relative;
  animation: pulse 2s infinite;
}

.dashboard-stats {
  display: flex;
  gap: 1rem;
}

.stat-item {
  text-align: right;
}

.stat-label {
  font-size: 0.65rem;
  color: #94a3b8;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 2px;
}

.stat-value {
  font-size: 0.8rem;
  color: #e2e8f0;
  font-weight: 500;
  font-family: "JetBrains Mono", monospace;
}

.status-active {
  color: #4ade80;
  position: relative;
}

.status-active::before {
  content: "●";
  font-size: 0.7rem;
  margin-right: 4px;
}

.dashboard-content {
  position: relative;
  padding: 1rem 1.2rem;
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
}

.progress-indicator {
  width: 100%;
  position: relative;
  margin-bottom: 1rem;
  padding: 0 0.25rem;
}

.progress-bar {
  height: 3px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  width: 40%;
  background: linear-gradient(90deg, #4f46e5, #06b6d4);
  border-radius: 3px;
  position: relative;
  animation: progress 2s infinite;
}

.progress-pulse {
  position: absolute;
  top: -3px;
  right: 60%;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #06b6d4;
  box-shadow: 0 0 8px rgba(6, 182, 212, 0.7);
  animation: movePulse 2s infinite;
}

.content-wrapper {
  display: flex;
  background: rgba(30, 41, 59, 0.7);
  border-radius: 8px;
  border: 1px solid rgba(99, 102, 241, 0.2);
  overflow: hidden;
  flex: 1;
  height: 100%;
}

.line-numbers {
  padding: 1rem 0.5rem;
  background: rgba(15, 23, 42, 0.5);
  color: #64748b;
  font-family: "JetBrains Mono", "Consolas", monospace;
  font-size: 0.85rem;
  line-height: 1.7;
  text-align: right;
  min-width: 2.5rem;
  user-select: none;
  border-right: 1px solid rgba(99, 102, 241, 0.2);
  overflow-y: hidden;
}

.line-number {
  padding: 0 0.5rem;
}

.content-area {
  position: relative;
  height: 100%;
  max-height: none;
  overflow-y: auto;
  font-family: "JetBrains Mono", "Consolas", monospace;
  font-size: 0.95rem;
  line-height: 1.7;
  color: #ffffff;
  padding: 1rem;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  background: transparent;
  border-radius: 0;
  border: none;
  flex: 1;
}

.content-area pre {
  margin: 0;
  font-family: inherit;
}

.content-area code {
  font-family: inherit;
}

/* 自定义滚动条样式 */
.content-area::-webkit-scrollbar {
  width: 6px;
}

.content-area::-webkit-scrollbar-track {
  background: rgba(15, 23, 42, 0.3);
  border-radius: 3px;
}

.content-area::-webkit-scrollbar-thumb {
  background: rgba(99, 102, 241, 0.5);
  border-radius: 3px;
}

.content-area::-webkit-scrollbar-thumb:hover {
  background: rgba(99, 102, 241, 0.7);
}

@keyframes glow {
  0%, 100% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
  }
}

@keyframes pulse {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.1);
    opacity: 0.8;
  }
}

@keyframes progress {
  0% {
    width: 35%;
    background: linear-gradient(90deg, #4f46e5, #06b6d4);
  }
  50% {
    width: 65%;
    background: linear-gradient(90deg, #4f46e5, #8b5cf6);
  }
  100% {
    width: 35%;
    background: linear-gradient(90deg, #4f46e5, #06b6d4);
  }
}

@keyframes movePulse {
  0% {
    right: 65%;
  }
  50% {
    right: 35%;
  }
  100% {
    right: 65%;
  }
}

/* 代码高亮 - 仪表盘深色主题 */
.code-highlight {
  color: #ffffff;
}

.code-highlight .tag {
  color: #a5b4fc;
  font-weight: 600;
  text-shadow: 0 0 4px rgba(165, 180, 252, 0.5);
}

.code-highlight .attribute {
  color: #fcd34d;
  font-weight: 600;
  text-shadow: 0 0 4px rgba(252, 211, 77, 0.5);
}

.code-highlight .value {
  color: #6ee7b7;
  font-weight: 500;
  text-shadow: 0 0 4px rgba(110, 231, 183, 0.5);
}

.code-highlight .comment {
  color: #94a3b8;
  font-style: italic;
  opacity: 0.8;
}

.code-highlight .indent {
  margin-left: 20px;
}

/* 打字光标动画 - 仪表盘样式 */
.typing-cursor {
  display: inline-block;
  width: 2px;
  height: 1.2em;
  background-color: #6366f1;
  margin-left: 2px;
  animation: blink 1s step-end infinite;
  vertical-align: middle;
  box-shadow: 0 0 5px rgba(99, 102, 241, 0.7);
}

/* 仪表盘淡入动画 */
.fade-in {
  animation: fadeIn 0.4s ease-in forwards;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
</style> 